package com.msda.service.staff.Impl;

import cn.dev33.satoken.secure.SaSecureUtil;
import cn.hutool.core.lang.UUID;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.msda.pojo.dto.PageDTO;
import com.msda.pojo.dto.TokenDTO;
import com.msda.pojo.dto.staff.FrozenUserDTO;
import com.msda.pojo.dto.staff.ResetPasswordDTO;
import com.msda.pojo.dto.staff.UserDTO;
import com.msda.pojo.dto.staff.UserLoginDTO;
import com.msda.pojo.entity.Token;
import com.msda.pojo.entity.staff.Customer;
import com.msda.pojo.entity.staff.CustomerDetail;
import com.msda.pojo.entity.staff.User;
import com.msda.exception.database.DatabaseOperationException;
import com.msda.mapper.CustomerMapper;
import com.msda.mapper.TokenMapper;
import com.msda.mapper.UserMapper;
import com.msda.service.staff.UserService;
import com.msda.utils.ImageCompressor;
import com.msda.utils.SnowFlakeID;
import com.msda.utils.strategy.UserContext;
import com.msda.utils.strategy.UserStrategy;
import com.msda.pojo.vo.UserLoginVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.*;
import java.util.zip.DataFormatException;

import static com.msda.constant.MessageConstant.*;


@Service
public class UserServiceImpl implements UserService {


    @Autowired
    private UserMapper userMapper;
    @Autowired
    private CustomerMapper customerMapper;
    @Autowired
    private TokenMapper tokenMapper;



    @Override
    public String userRegister(UserDTO userDTO) throws IOException {
        Map<String, UserStrategy> map = new HashMap<>();
        map.put("staff",UserStrategy.Staff);
        map.put("admin",UserStrategy.Administrator);
        map.put("customer",UserStrategy.Customer);

        if(judgeUserExistByAccount(userDTO.getAccount())){
            throw new DatabaseOperationException(ACCOUNT_EXIST);
        }
        userDTO.setId(SnowFlakeID.getSnowflakeId());
        userDTO.setCreatedDate(System.currentTimeMillis());
        userDTO.setPassword(SaSecureUtil.md5(userDTO.getPassword()));
        String Id = userDTO.getId();
        String role = userDTO.getRole();
        UserContext context = new UserContext(userMapper,customerMapper);
        map.get(role).register(userDTO,context);
        return Id;
    }

    @Override
    public Object getUser(String userId) {
        Map<String, UserStrategy> map = new HashMap<>();
        map.put("staff",UserStrategy.Staff);
        map.put("admin",UserStrategy.Administrator);
        map.put("customer",UserStrategy.Customer);

        User user = userMapper.selectById(userId);
        if(user == null){
            return user;
        }
        String role = user.getRole();
        UserContext context = new UserContext(userMapper,customerMapper);
        return map.get(role).getUser(user,context);
    }

    @Override
    public Object deleteUser(List<String> userIds) {
        List<String> errorId = new ArrayList<>();
        if(userIds == null || userIds.isEmpty()){
            throw new DatabaseOperationException("一个id都没有T:T");
        }
        int length = userIds.size();
        int i = 0;
        for(String userId : userIds){
            User user = userMapper.selectById(userId);
            if(user == null){
                errorId.add(userId);
                continue;
            }
            String role = user.getRole();
            if(role.equals("customer")){
                QueryWrapper<CustomerDetail> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("user_id",userId);
                customerMapper.delete(queryWrapper);
            }
            i += userMapper.deleteById(userId);
        }
        if(i == length){
            return "success";
        }
        return errorId;
    }

    @Override
    public Object updateUser(UserDTO userDTO) throws DataFormatException {
        Map<String, UserStrategy> map = new HashMap<>();
        map.put("staff",UserStrategy.Staff);
        map.put("admin",UserStrategy.Administrator);
        map.put("customer",UserStrategy.Customer);
        User user = userMapper.selectById(userDTO.getId());
        if(user == null){
            throw new DataFormatException(USER_NOT_EXIST);
        }
        if(userDTO.getAccount() != null){
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("account",userDTO.getAccount()).ne("id",userDTO.getId());
            long i = userMapper.selectCount(queryWrapper);
            if(i >= 1){
                throw new DatabaseOperationException("要修改的账号已存在！");
            }
        }
        if(userDTO.getPassword() != null){
            userDTO.setPassword(SaSecureUtil.md5(userDTO.getPassword()));
        }

        String role = userDTO.getRole();
        UserContext context = new UserContext(userMapper,customerMapper);
        return map.get(role).updateUser(userDTO,context);
    }

    //登录
    @Override
    public UserLoginVO login(UserLoginDTO userLoginDTO) {

        userLoginDTO.setPassword(SaSecureUtil.md5(userLoginDTO.getPassword()));
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("account",userLoginDTO.getAccount()).eq("password",userLoginDTO.getPassword());
        User user =  userMapper.selectOne(queryWrapper);
        if(user == null){
            throw new DatabaseOperationException(PASSWORD_or_ACCOUNT_ERROR);
        }
        if(user.isFrozen()){
            throw new DatabaseOperationException("账号被冻结！");
        }
        return getLoginUser(user.getId(),userLoginDTO.getAccount());
    }

    @Override
    public Object autoLogin(TokenDTO tokenDTO) {
        QueryWrapper<Token> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("token",tokenDTO.getToken());
        Token token = tokenMapper.selectOne(queryWrapper);
        if(token == null){
            throw new DatabaseOperationException("token错误！没有存储这个token");
        }
        QueryWrapper<User> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("account",token.getAccount());
        Long i = userMapper.selectCount(queryWrapper1);
        if(i > 1){
            System.out.println(i);
            throw new DatabaseOperationException("管理员乱插数据出事了！一个token匹配出的账号不止一个！！");
        }

        User user = userMapper.selectOne(queryWrapper1);
        if(user.isFrozen()){
            throw new DatabaseOperationException("账号被冻结！");
        }
        return getLoginUser(user.getId(),token.getAccount());
    }

    @Override
    public Long getAllStaffCount() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role","staff");
        Long i = userMapper.selectCount(queryWrapper);
        return i;
    }

    @Override
    public Long getAllCustomerCount() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role","customer");
        Long i = userMapper.selectCount(queryWrapper);
        return i;
    }

    @Override
    public List<User> getAllStaffPage(PageDTO pageDTO) {
        Page<User> page = new Page<>(pageDTO.getPage(),pageDTO.getSize());
        QueryWrapper<User> queryWrapper =new QueryWrapper<>();
        queryWrapper.eq("role","staff");
        queryWrapper.orderByDesc("created_date");
        page = userMapper.selectPage(page,queryWrapper);
        for(User user : page.getRecords()){
            user.setPassword(null);
        }
        return page.getRecords();
    }

    @Override
    public List<Customer> getAllCustomerPage(PageDTO pageDTO) {

        Page<User> page = new Page<>(pageDTO.getPage(),pageDTO.getSize());
        QueryWrapper<User> queryWrapper =new QueryWrapper<>();
        queryWrapper.eq("role","customer");
        queryWrapper.orderByDesc("created_date");
        page = userMapper.selectPage(page,queryWrapper);

        List<Customer> customer = new ArrayList<>();
        for(User user : page.getRecords()){
            customer.add((Customer) getUser(user.getId()));
        }
        return customer;
    }

    @Override
    public Object frozenUser(FrozenUserDTO frozenUserDTO) {
        QueryWrapper<User> queryWrapper =new QueryWrapper<>();
        queryWrapper.eq("account",frozenUserDTO.getAccount());
        User user = userMapper.selectOne(queryWrapper);
        user.setFrozen(frozenUserDTO.isFrozen());
        int i = userMapper.updateById(user);
        if(i < 1){
            throw new DatabaseOperationException("修改状态失败！");
        }
        return "OK";
    }

    @Override
    public Object userResetPassword(ResetPasswordDTO resetPasswordDTO) {
        if(resetPasswordDTO.getVerificationCode() != 123456){
            throw new DatabaseOperationException("验证码错误");
        }
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("account",resetPasswordDTO.getAccount());
        User user = userMapper.selectOne(queryWrapper);
        if(user == null){
            throw new DatabaseOperationException("账号错误！没有这个账号");
        }
        user.setPassword(SaSecureUtil.md5(resetPasswordDTO.getPassword()));
        userMapper.updateById(user);
        return "OK";
    }

    public UserLoginVO getLoginUser(String userId, String account){
        User aimUser = (User) getUser(userId);
        QueryWrapper<Token> tokenWrapper = new QueryWrapper<>();
        tokenWrapper.eq("account",account);
        Token tokenObject = tokenMapper.selectOne(tokenWrapper);
        aimUser.setPassword(null);
        if(tokenObject == null){
            String tokenNew = UUID.randomUUID().toString(true);
            Token token1 = new Token(SnowFlakeID.getSnowflakeId(),tokenNew,account,LocalDateTime.now());
            tokenMapper.insert(token1);
            return UserLoginVO.builder()
                    .user(aimUser)
                    .token(tokenNew)
                    .build();
        }
        tokenObject.setToken(UUID.randomUUID().toString(true));
        tokenObject.setExpireTime(LocalDateTime.now());
        tokenMapper.updateById(tokenObject);
        return UserLoginVO.builder()
                .user(aimUser)
                .token(tokenObject.getToken())
                .build();
    }

    public boolean judgeUserExistByAccount(String account){
        if(account == null){
            return false;
        }
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("account",account);
        User user = userMapper.selectOne(queryWrapper);
        if(user == null){
            return false;
        }
        return true;
    }

    @Override
    public Object set_profilePicture(String id, MultipartFile image) throws IOException {
        User user = userMapper.selectById(id);
        if(user == null){
            throw new DatabaseOperationException("用户不存在！");
        }
        String fileName = uploadImage(image);
        user.setAvatar(fileName);
        userMapper.updateById(user);
        return fileName;
    }

    private  String uploadImage(MultipartFile image) throws IOException {
        byte[] compressedImage = ImageCompressor.compressToMaxSize(image);
        String originalFilename = image.getOriginalFilename();
        String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
        String newFilename = UUID.randomUUID().toString(true) + fileExtension;
        if (newFilename.contains("..")) {
            throw new IOException("抱歉! 文件名包含无效路径序列: " + newFilename);
        }
        Path targetLocation = Paths.get("/avator").resolve(newFilename);
        Files.write(targetLocation,compressedImage);
        return newFilename;
    }



}
